package br.com.conciliador.consulta.negocio;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;

import br.com.conciliador.cadastro.negocio.DatasNgc;
import br.com.conciliador.cadastro.vo.DatasVo;
import br.com.conciliador.consulta.vo.ExtratoVo;
import br.com.conciliador.util.hibernate.business.R2HbNgc;
import br.com.r2.util.hibernate.business.RestritorHb;
import br.com.r2.util.tipodado.Moeda;

public class ExtratoNgc extends R2HbNgc<ExtratoVo>
{

   private Map filtroPropriedade = new HashMap();
   private Map restritores = new HashMap();
   
   private static ExtratoNgc instancia = null;
   
   private ExtratoNgc()
   {
      init(restritores, filtroPropriedade, ExtratoVo.class);
      addFiltro("extratoPK.codigoDataLancamento", RestritorHb.RESTRITOR_GE, "filtro.codigoDataLancamentoInicial");
      addFiltro("extratoPK.codigoDataLancamento", RestritorHb.RESTRITOR_LE, "filtro.codigoDataLancamentoFinal");
      addFiltro("extratoPK.dataLancamento", RestritorHb.RESTRITOR_DATA_INICIAL, "filtro.dataLancamentoInicial");
      addFiltro("extratoPK.dataLancamento", RestritorHb.RESTRITOR_DATA_FINAL, "filtro.dataLancamentoFinal");
      addFiltro("extratoPK.conta", RestritorHb.RESTRITOR_EQ, "extratoPK.conta");
      addFiltro("extratoPK.loja", RestritorHb.RESTRITOR_EQ, "extratoPK.loja");
      addFiltro("extratoPK.rede", RestritorHb.RESTRITOR_IN, "filtro.listaRede");
      addFiltro("extratoPK.loja", RestritorHb.RESTRITOR_IN, "filtro.listaEstLoja");
      addFiltro("extratoPK.bandeira", RestritorHb.RESTRITOR_EQ, "extratoPK.bandeira");
      addFiltro("extratoPK.produto", RestritorHb.RESTRITOR_EQ, "extratoPK.produto");
      addFiltro("extratoPK.tipoHistorico", RestritorHb.RESTRITOR_EQ, "extratoPK.tipoHistorico");

   }
   
   public static ExtratoNgc getInstancia()
   {
       if (instancia == null)
       {
           instancia = new ExtratoNgc();
       }
       return instancia;
   }

   @Override
   protected Map filtroPropriedade()
   {
       return filtroPropriedade;
   }

   @Override
   protected Criteria montaCriteria(Session sessao, int join)
   {
       Criteria criteria = sessao.createCriteria(ExtratoVo.class);
       return criteria;
   }

   @Override
   protected Map restritores()
   {
       return restritores;
   }
   
   @Override
   protected void setarOrdenacao(Criteria criteria, ExtratoVo filter, int join)
   {
      criteria.addOrder(Order.asc("extratoPK.dataLancamento"));
   }
   
   @Override
   public List<ExtratoVo> pesquisar(Session session, ExtratoVo filter, int join)
         throws Exception
   {
	   
	 int fator = 1;
	 double saldo  = 0;
	 double valor = 0;
	 
	 Criteria criteria = this.montaCriteria(session, join);

	 this.setarOrdenacao(criteria, filter, join);

	 this.restringir(criteria, filter);
		
	 this.setNumeroMaximoRegistros(session, criteria, filter, join);

	 List<ExtratoVo> listaLancamentos = criteria.list();
     if(listaLancamentos != null && listaLancamentos.size() > 0)
      {
         for(int i = 0; i < listaLancamentos.size(); i++)
         {
     		if ("C".equals(listaLancamentos.get(i).getTipoLancamento().getValor()))
    		{
                fator = 1;
    		}
    		else if ("D".equals(listaLancamentos.get(i).getTipoLancamento().getValor()))
    		{
    			fator = -1;
    		}
        	 
        	 if (i > 0)
        	{
        		saldo = listaLancamentos.get(i-1).getSaldo().getValor() + (listaLancamentos.get(i).getExtratoPK().getValorLancamento().getValor() * fator); 
        		listaLancamentos.get(i).setSaldo(new Moeda(saldo)); 
        	}
        	else
        	{
        		listaLancamentos.get(i).setSaldo(new Moeda(listaLancamentos.get(i).getExtratoPK().getValorLancamento().getValor() * fator));
        	}
         }
      }
      return listaLancamentos;
   }

   private void setFiltroPeriodoDataLancamento(Session sessao, ExtratoVo filter) throws Exception 
   {
		
	   DatasVo vo = new DatasVo();
	   vo.setData(filter.getFiltro().getDataLancamentoInicial());
		
	   DatasVo retornoVo = DatasNgc.getInstancia().get(sessao, vo, 0);
		
	   if (retornoVo != null)
	   {
		   filter.getFiltro().setCodigoDataLancamentoInicial(retornoVo.getCodigo());
		   filter.getFiltro().setDataLancamentoInicial(null);
	   }
		
	   if (filter.getFiltro().getDataLancamentoFinal() != null && filter.getFiltro().getDataLancamentoFinal().isPreenchido())
	   {
		   vo = new DatasVo();
		   vo.setData(filter.getFiltro().getDataLancamentoFinal());
			
		   retornoVo = DatasNgc.getInstancia().get(sessao, vo, 0);
			
		   if (retornoVo != null)
		   {
			   filter.getFiltro().setCodigoDataLancamentoFinal(retornoVo.getCodigo());
			   filter.getFiltro().setDataLancamentoFinal(null);
		   }
	   }
   }
}
